/**
 * @author cqb 2016-04-27.
 * @module CheckBoxGroup
 */

import React from 'react';
import classNames from 'classnames';
import PropTypes from 'prop-types';
import CheckBox from '../Input/Checkbox';


/**
 * CheckBoxGroup 类
 * @class CheckBoxGroup
 * @constructor
 * @extend React.Component
 */
class CheckBoxGroup extends React.Component {
    static displayName = 'CheckBoxGroup';

    static propTypes = {
        /**
         * 数据源
         * @attribute data
         * @type {Array}
         */
        data: PropTypes.any,
        /**
         * 默认值
         * @attribute value
         * @type {String}
         */
        value: PropTypes.string,
        /**
         * 组名
         * @attribute name
         * @type {String}
         */
        name: PropTypes.string,
        /**
         * class样式名称
         * @attribute className
         * @type {String}
         */
        className: PropTypes.string,
        /**
         * 行式inline、堆积stack布局
         * @attribute layout
         * @type {String}
         */
        layout: PropTypes.oneOf(['inline', 'stack']),
        /**
         * value字段
         * @attribute valueField
         * @type {String}
         */
        valueField: PropTypes.string,
        /**
         * 显示字段
         * @attribute textField
         * @type {String}
         */
        textField: PropTypes.string,
        /**
         * 值变化回调
         * @attribute onChange
         * @type {Function}
         */
        onChange: PropTypes.func
    };

    static defaultProps = {
        value: '',
        data: [],
        layout: 'inline',
        valueField: 'id',
        textField: 'text',
        disabled: false
    };

    itemMap = {};

    state = {
        value: `${this.props.value}`
    }

    /**
     * 记录当前的checkbox对象
     * @param {[type]} ref [description]
     */
    addCheckBox = (value, ref) => {
        if (ref) {
            this.itemMap[value] = ref;
        }
    }

    /**
     * 子元素移除后回调， 删除记录的对象
     * @param  {[type]} item [description]
     * @return {[type]}      [description]
     */
    unbind = (value) => {
        delete this.itemMap[value];
    }

    /**
     * 值变化回调
     * @method handleChange
     * @param value {String} 当前操作对象的值
     * @param checked   {Boolean} 知否选中
     * @param event     {Event} 事件对象
     * @param item  {Object} 当前操作对象
     */
    onChange = (v, checked) => {
        if (this.props.disabled) {
            return;
        }

        let current = this.state.value;
        current = current !== undefined && current !== null ? current : '';
        current = current.split(',');

        const ret = [];
        for (const value in this.itemMap) {
            const item = this.itemMap[value];
            if (value === v) {
                if (checked) {
                    ret.push(value);
                }
            } else {
                if (item.props.checked) {
                    ret.push(value);
                }
            }
        }

        this.setState({
            value: ret.join(',')
        }, () => {
            if (this.props.onChange) {
                this.props.onChange(ret.join(','));
            }
        });
    }

    buildData (data) {
        if (data instanceof Array) {
            if (data.length && typeof data[0] === 'object') {
                return data;
            }
            if (data.length && typeof data[0] === 'string') {
                data = data.map((item, index) => {
                    return {
                        id: index,
                        text: item
                    };
                });
                return data;
            }
            return data;
        } else if (typeof data === 'object') {
            const arr = [];
            for (const key in data) {
                arr.push({
                    id: key,
                    text: data[key]
                });
            }
            return arr;
        } else {
            return data;
        }
    }

    /**
     * 渲染子节点
     * @method renderItems
     * @returns {Array} 子对象
     * @private
     */
    renderItems () {
        let {valueField, textField, name, data} = this.props;
        data = data || [];
        data = this.buildData(data);

        const values = this.state.value === undefined ? [] : this.state.value.split(',');
        return data.map((item) => {
            const value = `${item[valueField]}`;
            const text = item[textField];
            const checked = values.indexOf(value) != -1;

            return (<CheckBox key={value}
                name={name}
                ref={this.addCheckBox.bind(this, value)}
                unbind={this.unbind.bind(this, value)}
                disabled={item._disabled || this.props.disabled}
                value={value}
                label={text}
                checked={checked}
                onChange={this.onChange}
            />);
        }, this);
    }

    setValue (value) {
        this.setState({value});
    }

    render () {
        let {className, layout, style} = this.props;
        className = classNames(
            className,
            'cm-checkbox-group',
            {
                'cm-checkbox-group-stack': layout === 'stack'
            }
        );

        return (
            <div className={className} style={style}>
                {this.renderItems()}
            </div>
        );
    }
}

export default CheckBoxGroup;
